package com.kapcb.mvc.advice;

import com.kapcb.common.enums.ResultCodeEnum;
import com.kapcb.common.result.ResultMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;

/**
 * <a>Title: RestControllerAdvance </a>
 * <a>Author: kapcb <a>
 * <a>Description: RestControllerAdvance <a>
 *
 * @author Kpacb
 * @version 1.0
 * @date 2024/6/11 23:06
 * @since 1.0
 */
@Slf4j
@RestControllerAdvice
public class RestControllerAdvance {

    /**
     * 路径变量校验失败，会抛出 ConstraintViolationException 异常，通过异常统一处理来对此异常进行处理
     *
     * @param e a {@link javax.validation.ConstraintViolationException} object.
     * @return ResultMessage<Object> {@link com.kapcb.common.result.ResultMessage} 返回结果
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public ResultMessage<Object> constraintViolationExceptionHandler(ConstraintViolationException e) {
        String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).findFirst().orElse(null);
        return ResultMessage.failure(ResultCodeEnum.REQUEST_PARAM_VALIDATE_FAIL.code(), message);
    }

    /**
     * 请求体类型参数校验失败，会抛出 MethodArgumentNotValidException 异常
     *
     * @param e a {@link org.springframework.web.bind.MethodArgumentNotValidException} object.
     * @return ResultMessage<Object> {@link com.kapcb.common.result.ResultMessage} 返回结果
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultMessage<Object> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        try {
            BindingResult exceptions = e.getBindingResult();
            if (exceptions.hasErrors()) {
                List<ObjectError> allErrors = exceptions.getAllErrors();
                if (!allErrors.isEmpty()) {
                    FieldError fieldError = (FieldError) allErrors.get(0);
                    return ResultMessage.failure(ResultCodeEnum.REQUEST_PARAM_VALIDATE_FAIL.code(), fieldError.getDefaultMessage());
                }
            }
        } catch (Exception exception) {
            return ResultMessage.failure(ResultCodeEnum.REQUEST_PARAM_VALIDATE_FAIL.code(), "请求参数校验异常!");
        }
        return ResultMessage.failure(ResultCodeEnum.REQUEST_PARAM_VALIDATE_FAIL.code(), "请求参数校验不通过!");
    }

    /**
     * UNIQUE 索引，数据重复异常
     */
//    @ExceptionHandler(DuplicateKeyException.class)
//    public ResultMessage<Void> handleDuplicateKeyException(DuplicateKeyException e, HttpServletRequest request) {
//        String requestURI = request.getRequestURI();
//        log.error("请求地址'{}', 数据库中已存在记录'{}'", requestURI, e.getMessage());
//        return ResultMessage.failure(ResultCodeEnum.BUSINESS_ERROR.code(), "数据库中已存在该记录，请联系管理员确认");
//    }
}
